package ar.edu.itba.it.paw.web;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import ar.edu.itba.it.paw.domain.OrderProducts;
import ar.edu.itba.it.paw.domain.User;
import ar.edu.itba.it.paw.domain.exceptions.RegisteredMailException;
import ar.edu.itba.it.paw.domain.exceptions.RegisteredUsernameException;
import ar.edu.itba.it.paw.services.ProductServices;
import ar.edu.itba.it.paw.services.UserServices;
import ar.edu.itba.it.paw.web.command.EditUserForm;
import ar.edu.itba.it.paw.web.command.LoginUserForm;
import ar.edu.itba.it.paw.web.command.RegisterUserForm;
import ar.edu.itba.it.paw.web.validator.EditUserFormValidator;
import ar.edu.itba.it.paw.web.validator.LoginUserFormValidator;
import ar.edu.itba.it.paw.web.validator.RegisterUserFormValidator;

@Controller
public class UserController {

	private UserServices user_service;
	private ProductServices product_service;
	private LoginUserFormValidator login_validator;
	private RegisterUserFormValidator register_validator;
	private EditUserFormValidator edit_validator;
	
	@Autowired
	public UserController(UserServices userService, ProductServices product_service, LoginUserFormValidator login_validator,
			RegisterUserFormValidator register_validator, EditUserFormValidator edit_validator){
		this.user_service = userService;
		this.product_service = product_service;
		this.login_validator = login_validator;
		this.register_validator = register_validator;
		this.edit_validator = edit_validator;
	}
	
	
	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView index(HttpSession session, HttpServletRequest req) throws Exception{
		
		ModelAndView mav = new ModelAndView("user/logged");
		ModelAndView mav2 = new ModelAndView();
		
		User user = (User) session.getAttribute("usuario");
		
		/*Corregir lo que hace al capturar la excepcion*/
		if(user != null){
			mav.addObject("productList",product_service.getOtherUserProducts(user));
			if(user.isAdmin()){
				mav.addObject("admin",true);
			}else{
				mav.addObject("admin",false);
			}
			return mav;
		}
		
		mav2.addObject("lastProductList",product_service.getAllProducts(new OrderProducts("fechaPublicacion",false,5)));
		mav2.addObject("viewedProductList",product_service.getVisitedProducts());
		
		if(req.getParameter("red") != null)
			mav2.addObject("red", 1);
				
		mav2.addObject("loginUserForm", new LoginUserForm());
		return mav2;
	}
	
	@RequestMapping(method = RequestMethod.POST)
	public ModelAndView index(HttpSession session, LoginUserForm loginUserForm, Errors errors) throws Exception{
		
		login_validator.validate(loginUserForm, errors);
		
		if(errors.hasErrors()){
			ModelAndView mav = new ModelAndView();
			mav.addObject("lastProductList",product_service.getAllProducts(new OrderProducts("fechaPublicacion",false,5)));
			mav.addObject("viewedProductList",product_service.getVisitedProducts());	
			return mav;
		}
		if(!user_service.authenticate(loginUserForm.getUsername(), loginUserForm.getPassword())){
			ModelAndView mav = new ModelAndView();
			mav.addObject("lastProductList",product_service.getAllProducts(new OrderProducts("fechaPublicacion",false,5)));
			mav.addObject("viewedProductList",product_service.getVisitedProducts());	
			errors.rejectValue("username", "wrong");
			return mav;
		}
		
		
		User user = user_service.getUser(loginUserForm.getUsername());
		session.setAttribute("usuario", user);
		
		ModelAndView mav = new ModelAndView("user/logged");
		if(user.isAdmin()){
			mav.addObject("admin",true);
		}else{
			mav.addObject("admin",false);
		}
		mav.addObject("productList",product_service.getOtherUserProducts(user));		
		return mav;

	}
	
	
	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView register(HttpSession session) throws Exception{

		ModelAndView mav = new ModelAndView("user/logged");
		User user = (User) session.getAttribute("usuario");
		
		/*Corregir lo que hace al capturar la excepcion*/
		if (user != null) {
			mav.addObject("productList",product_service.getOtherUserProducts(user));
			mav.addObject("regError", 0);
			return mav;
		}

		return new ModelAndView().addObject("registerUserForm", new RegisterUserForm());
	}
	
	
	@RequestMapping(method = RequestMethod.POST)
	public String register(RegisterUserForm registerUserForm, Errors errors) {
		register_validator.validate(registerUserForm, errors);
		if(errors.hasErrors()){
			return null;
		}
		try{
			user_service.addUser(new User(registerUserForm.getUsername(),registerUserForm.getConf_password(),registerUserForm.getName(),registerUserForm.getSurname(),registerUserForm.getMail()));
		}catch(RegisteredUsernameException e){
			errors.rejectValue("username", "existent");
			return null;
		}catch(RegisteredMailException e){
			errors.rejectValue("mail", "exists");
			return null;
		}
		return "user/registered";
	}
	
	
	@RequestMapping(method = RequestMethod.GET)
	public String logout(HttpSession session){
		
		session.invalidate();
		return "redirect:index";
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView editUser(HttpSession session) {
		ModelAndView mav = new ModelAndView();
		User user = (User)session.getAttribute("usuario");
		
		mav.addObject("editUserForm", new EditUserForm(user.getUsername(), user.getFirst_name(), user.getLast_name()));
		return mav;
	}
	
	@RequestMapping(method = RequestMethod.POST)
	public String editUser(HttpSession session, EditUserForm editUserForm, Errors errors) {
		edit_validator.validate(editUserForm, errors);
		if(errors.hasErrors()){
			return null;
		}

		User user = ((User)session.getAttribute("usuario"));
		if(!editUserForm.getOld_password().equals("")){
			if(!user.getPassword().equals(editUserForm.getOld_password())){
				errors.rejectValue("old_password", "wrong");
				return null;
			}
		}
		System.out.println("before " + user);
		editUserForm.updateUser(user);
		System.out.println("after " + user);
		
		user_service.updateUser(user);
		
		session.setAttribute("usuario", user);
		
		return "user/edited";
	}
}
